#include <stdio.h>
#include <string.h>

#include <zlib.h>


#define 	BUFSIZE 	5000
#define     TESTSTR     "hello zlib!!"

// deflateInit() + deflate() + deflateEnd()
// inflateInit() + inflate() + inflateEnd()

int main( int argc, char* argv[] )
{
	int 		ret;
	int 		err;
	int 		t1,t2;
	int 		s_size;
	int 		d_size;
    int         un_size;
	char 		s_str[BUFSIZE];
	char 		d_str[BUFSIZE];
    char        un_str[BUFSIZE];
	z_stream 	c_stream;
    //z_stream    c_stream;

	memset( s_str, 0, strlen( s_str ) );
	memset( d_str, 0, strlen( d_str ) );
    memset( un_str, 0, strlen( un_str ) );

	// s_str
	strcpy( s_str, TESTSTR );
	s_size = strlen( s_str );

	// 圧縮
	c_stream.zalloc = (alloc_func)0;
    c_stream.zfree = (free_func)0;
    c_stream.opaque = (voidpf)0;

    // 初期化
    err = deflateInit( &c_stream, Z_DEFAULT_COMPRESSION );
    printf( "deflateInit - err: %d\n", err );

    // 圧縮元・圧縮先バッファー設定
    c_stream.next_in  = (Bytef*)s_str;
    c_stream.next_out = d_str;

    t1 = sizeof( d_str );

    // ====================================================
    // 圧縮
    while( c_stream.total_in != s_size && c_stream.total_out < t1 ){
        c_stream.avail_in = c_stream.avail_out = 1;
        err = deflate( &c_stream, Z_NO_FLUSH );
        printf( "deflate1 - err: %d\n", err );
    }
    // Finish the stream, still forcing small buffers:
    for ( ; ; ) {
        c_stream.avail_out = 1;
        err = deflate(&c_stream, Z_FINISH);
        if (err == Z_STREAM_END){
        	break;
        }
        printf( "deflate2 - err: %d\n", err );
    }

    // 圧縮終了処理
    err = deflateEnd(&c_stream);
    printf( "deflateEnd - err: %d\n", err );

    // ====================================================
    // 解凍
    c_stream.zalloc = (alloc_func)0;
    c_stream.zfree = (free_func)0;
    c_stream.opaque = (voidpf)0;

    c_stream.next_in  = d_str;
    c_stream.avail_in = (uInt)t1;
    c_stream.next_out = un_str;

    // 解凍初期化
    err = inflateInit(&c_stream);
    printf( "inflateInit - err: %d\n", err );

    t2 = sizeof( c_stream );

    // 解凍
    while( c_stream.total_out < t2 && c_stream.total_in < t1 ) {
        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
        err = inflate(&c_stream, Z_NO_FLUSH);
        if (err == Z_STREAM_END){
            break;
        }
        printf( "inflate - err: %d\n", err );
    }

    err = inflateEnd(&c_stream);
    printf( "inflateEnd - err: %d\n", err );

    printf("inflate(): %s\n", (char *)un_str);

    return 0;
}